package zxj.weixin.mp.service;

import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import zxj.weixin.mp.api.CardApi;
import zxj.weixin.mp.api.JsSdkApi;
import zxj.weixin.mp.domain.Account;
import zxj.weixin.mp.domain.CardBaseInfo;
import zxj.weixin.mp.domain.UserCard;
import zxj.weixin.mp.domain.message.CardCheckMsg;
import zxj.weixin.mp.domain.message.UserDelCardMsg;
import zxj.weixin.mp.domain.message.UserGetCardMsg;
import zxj.weixin.mp.mapper.CardBaseInfoMapper;
import zxj.weixin.mp.mapper.UserCardMapper;
import zxj.weixin.utils.RedisStringUtils;
import zxj.weixin.utils.RedisUtils;

/**
 * 微信卡券Service
 * 
 * @author zhuxuejiang
 *
 */
@Service
public class CardService {

	private static final Logger LOGGER = LoggerFactory.getLogger(CardService.class);

	private static final String KEY_CARD_API_TICKET = "wx_card_api_ticket.";
	private static final long TIMEOUT_CARD_API_TICKET = 60 * 60;

	private static final String KEY_CARD_QRCODE = "wx_card_qrcode.";
	private static final long TIMEOUT_CARD_QRCODE = 60 * 60;

	@Autowired
	private RedisUtils<String, Map<String, Object>> redisUtils;

	@Autowired
	private RedisStringUtils redisStringUtils;

	@Autowired
	private CardBaseInfoMapper cardBaseInfoMapper;

	@Autowired
	private UserCardMapper userCardMapper;

	@Autowired
	private AccountService accountService;

	@Autowired
	private UserCardService userCardService;

	@Autowired
	private WeixinService weixinService;

	/**
	 * 获取api_ticket调用卡券相关接口的临时票据
	 * 
	 * @param appId 公众号的唯一标识
	 * @return apiTicket 调用卡券相关接口的临时票据
	 * @throws Exception
	 */
	public String getApiTicket(String appId) throws Exception {
		if (StringUtils.isBlank(appId)) {
			return null;
		}

		String key = KEY_CARD_API_TICKET + appId;

		if (redisStringUtils.hasKey(key)) {
			return redisStringUtils.opsForValueGet(key);
		}

		String accessToken = weixinService.getAccessToken(appId);
		if (null == accessToken) {
			LOGGER.error("获取access_token错误!");
			return null;
		}

		Map<String, Object> resultMap = JsSdkApi.getWxCardTicket(accessToken);
		if (null == resultMap) {
			return null;
		}

		String ticket = (String) resultMap.get("ticket");
		if (null == ticket) {
			LOGGER.error("获取access_token错误!");
			return null;
		}

		redisStringUtils.opsForValueSet(key, ticket, TIMEOUT_CARD_API_TICKET);
		return ticket;
	}

	/**
	 * 创建二维码
	 * 
	 * @param appId 公众号的唯一标识
	 * @return apiTicket 调用卡券相关接口的临时票据
	 * @throws Exception
	 */
	public Map<String, Object> createQrCode(String appId, String cardId) throws Exception {
		if (StringUtils.isBlank(appId) || StringUtils.isBlank(cardId)) {
			return null;
		}

		String key = KEY_CARD_QRCODE + appId + "." + cardId;

		if (redisUtils.hasKey(key)) {
			return (Map<String, Object>) redisUtils.opsForValueGet(key);
		}

		String accessToken = weixinService.getAccessToken(appId);
		if (null == accessToken) {
			LOGGER.error("创建二维码错误!");
			return null;
		}

		Map<String, Object> cardMap = new HashMap<>(16);
		cardMap.put("card_id", cardId);
		cardMap.put("outer_str", "qrcode");

		Map<String, Object> actionMap = new HashMap<>(16);
		actionMap.put("card", cardMap);

		Map<String, Object> dataMap = new HashMap<>(16);
		dataMap.put("action_name", "QR_CARD");
		dataMap.put("action_info", actionMap);

		Map<String, Object> map = CardApi.createQrCode(accessToken, dataMap);
		if (null == map) {
			LOGGER.error("创建二维码错误!");
			return null;
		}

		redisUtils.opsForValueSet(key, map, TIMEOUT_CARD_QRCODE);
		return map;
	}

	/**
	 * 处理审核事件推送消息
	 * 
	 * @param msg 审核事件推送消息
	 */
	public void checkNotify(CardCheckMsg msg) {
		// 判断msg是否为空
		if (null == msg) {
			return;
		}

		// 判断cardId是否为空
		String cardId = msg.getCardId();
		if (StringUtils.isBlank(cardId)) {
			return;
		}

		// 判断CardBaseInfo是否存在
		CardBaseInfo cardBaseInfo = cardBaseInfoMapper.selectByPrimaryKey(cardId);
		if (null == cardBaseInfo) {
			return;
		}

		// 更新微信卡券的审核状态
		cardBaseInfo.setCheckState(msg.getEvent());
		cardBaseInfo.setRefuseReason(msg.getRefuseReason());
		cardBaseInfoMapper.updateByPrimaryKeySelective(cardBaseInfo);
	}

	/**
	 * 处理微信卡券领取事件推送
	 * 
	 * @param msg 领取事件推送消息
	 */
	public void userGetCardNotify(UserGetCardMsg msg) {
		// 判断msg是否为空
		if (null == msg) {
			return;
		}

		// 判断wxId是否为空
		String wxId = msg.getToUserName();
		if (StringUtils.isBlank(wxId)) {
			return;
		}

		// 判断account是否存在
		Account account = accountService.getByWxId(wxId);
		if (null == account) {
			return;
		}

		// 持久化微信公众号用户领取的会员卡
		UserCard userCard = new UserCard();
		userCard.setWxId(wxId);
		userCard.setAppId(account.getAppId());
		userCard.setOpenid(msg.getFromUserName());
		userCard.setCardId(msg.getCardId());
		userCard.setCardState("normal");
		userCard.setIsGiveByFriend(msg.getIsGiveByFriend() == 1 ? true : false);
		userCard.setFriendUserName(msg.getFriendUserName());
		userCard.setUserCardCode(msg.getUserCardCode());
		userCard.setOldUserCardCode(msg.getOldUserCardCode());
		userCard.setOuterStr(msg.getOuterStr());
		userCard.setIsRestoreMemberCard(msg.getIsRestoreMemberCard() == 1 ? true : false);
		userCard.setUnionid(msg.getUnionId());
		userCard.setOuterId(msg.getOuterId());
		userCard.setIsRecommendByFriend(msg.getIsRecommendByFriend() == 1 ? true : false);
		userCard.setSourceScene(msg.getSourceScene());

		// 判断userCard是否存在
		UserCard oldUserCard = userCardService.find(msg.getCardId(), msg.getUserCardCode());
		if (null == oldUserCard) {
			userCardMapper.insertSelective(userCard);
		} else {
			userCard.setId(oldUserCard.getId());
			userCardMapper.updateByPrimaryKeySelective(userCard);
		}
	}

	/**
	 * 处理微信卡券删除事件推送
	 * 
	 * @param msg 删除事件推送消息
	 */
	public void userDelCardNotify(UserDelCardMsg msg) {
		// 判断msg是否为空
		if (null == msg) {
			return;
		}

		// 判断userCard是否存在
		UserCard userCard = userCardService.find(msg.getCardId(), msg.getUserCardCode());
		if (null == userCard) {
			return;
		}

		userCard.setCardState("delete");
		userCardMapper.updateByPrimaryKeySelective(userCard);
	}

}
